<?php

namespace App\Listeners;

use App\Enum\BalanceLogEnum;
use App\Enum\CardEnum;
use App\Enum\ScheduleEnum;
use App\Enum\CodeEnum;
use App\Enum\EnterpriseCommuteEnum;
use App\Enum\UserCardsEnum;
use App\Enum\UserEnterpriseEnum;
use App\Enum\WalletsEnum;
use App\Events\CardPaySchedule;
use App\Http\Clients\ZccmzjgyxmClient;
use App\Models\CmzjScheduleModel;
use App\Models\UserCardsModel;
use App\Models\UserEnterpriseModel;
use App\Models\WalletModel;
use App\Services\CommonService;
use App\Services\EnterpriseCommuteService;
use App\Services\WalletService;
use GuzzleHttp\Exception\GuzzleException;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Support\Facades\Log;

class CardPayScheduleNotification implements ShouldQueue
{
    public $queue='card-pay';
    /**
     * Create the event listener.
     *
     * @return void
     */
    public function __construct()
    {
        //
    }

    /**
     * Handle the event.
     *
     * @param CardPaySchedule $event
     * @return void
     * @throws GuzzleException
     */
    public function handle(CardPaySchedule $event)
    {
        $schedule = $event->schedule;
        $payUnit = $schedule->pay_unit;

        Log::notice(sprintf("%s, 支付方式:%s", $schedule->memo, CardEnum::CARD_PAY_UNIT[$payUnit]));
        // 1. 扣
        $success = false;
        switch ( $payUnit ){
            case CardEnum::CARD_PAY_TYPE_POINT:
                $success = $this->_consumeCmzjPoint($schedule);
                break;
            case CardEnum::CARD_PAY_TYPE_SXCX_COIN:
                $success = $this->_consumeSxcxCoin($schedule);
                break;
        }
        Log::notice(sprintf("支付结果:%s", var_export($success,true)));

        // 2. 处理 订单已经处理
        if( $success ){
            $this->processReferId($schedule->refer_type, $schedule->refer_id);
        }
    }

    /**
     * 扣减 善行币
     *
     * @param $schedule
     * @return bool
     */
    private function _consumeSxcxCoin($schedule): bool
    {
        $dbRecord = CmzjScheduleModel::query()->find($schedule->id);

        try {
            $result = WalletService::deductSxcxCoin($schedule->user_id, $schedule->amount);

            // 成功
            if(!empty($result))
            {
                $dbRecord->status = ScheduleEnum::SCHEDULE_STATUS_SUCCESS;
                $success = true;
            }
            $dbRecord->result = '支付成功';

            if( $dbRecord->save() ) return true;
            else return false;

        } catch (\Exception $e){
            // 支付失败
            Log::error("扣减 善行币失败".$e->getMessage());

            $dbRecord->status = ScheduleEnum::SCHEDULE_STATUS_FAILED;
            $dbRecord->result = $e->getMessage();

            if( $dbRecord->save() ) return true;
            else return false;
        }
    }

    /**
     * 扣减 公益诚信积分
     * @param $schedule
     * @return bool
     * @throws GuzzleException
     */
    private function _consumeCmzjPoint($schedule): bool
    {
        $result = (new ZccmzjgyxmClient())->consumeCredits($schedule->phone, $schedule->refer_no, $schedule->amount, $schedule->memo);
        $dbRecord = CmzjScheduleModel::query()->find($schedule->id);

        if ($result['code'] != CodeEnum::SUCCESS) {
            $dbRecord->status = ScheduleEnum::SCHEDULE_STATUS_FAILED;
            $success = false;
        }else{
            $dbRecord->status = ScheduleEnum::SCHEDULE_STATUS_SUCCESS;
            $success = true;
        }
        $dbRecord->result = $result['msg'];
        $dbRecord->save();
        return $success;
    }
    private function processReferId( $referType, $referId)
    {
        try {
            Log::info('Coming processReferId');
            // 标识 卡已经付款
            $record = UserCardsModel::query()->find($referId);
            switch ($referType) {
                case CardEnum::CARD_TYPE_GYCX: // 购买公益出行卡
                    // 充值
                    WalletModel::query()->where(['user_id' => $record->user_id, 'user_type' => WalletsEnum::WALLET_USER_VILLAGER])->increment('gycx_axd', $record->value_sxcx);

                    $record->pay_status = UserCardsEnum::PAY_STATUS_PAYED;
                    $record->value_dispatch_status = UserCardsEnum::VALUE_DISPATCH_STATUS_DONE; // 值已经到账
                    $record->save();
                    break;

                case CardEnum::CARD_TYPE_ENTERPRISE_COMMUTE_10W: // 购买企业通勤产品
                    // 标识 卡已经付款
                    $record->pay_status = UserCardsEnum::PAY_STATUS_PAYED;
                    $record->save();
                    // 如果已经开通企业账号，则直接发放积分
                    $this->_dispatchEnterpriseCommuteAxd($record);
                    break;
            }

            // add log
            $this->_addLog($record);
        }catch( \Exception $e ){
            Log::error(' Async queue, CmzjScheduleNotification processReferId error. '. $e->getMessage());
        }
    }


    /**
     * 如果已经开通企业账号，则直接发放积分
     *
     * @param $userCard
     * @return void
     */
    private function _dispatchEnterpriseCommuteAxd($userCard)
    {
        try {
            $enterprise = UserEnterpriseModel::query()->where(['user_id' => $userCard->user_id, 'status' => UserEnterpriseEnum::STATUS_ACCOUNT_DONE])->first();
            // 如果企业账户已经开通，则发放积分
            if (!empty($enterprise) && $enterprise->tenant_id > 0) {
                $result = EnterpriseCommuteService::incrTenantAxd($enterprise->tenant_id, $userCard->value_sxcx);
                // 如果更新 成功，将卡标识 为已经充值
                if( !empty($result) && empty($result['code'])) {
                    $userCard->value_dispatch_status = UserCardsEnum::VALUE_DISPATCH_STATUS_DONE; // 值已经到账
                    $userCard->save();
                }
            }
        } catch(\Exception $e){
            Log::error("给消费企业通勤卡（充值）异常：".$e->getMessage());
        }
    }
    /**
     * 增加积分消耗log
     * 和
     * 增加积分充值log
     * @param $userCard
     * @return void
     */
    private function _addLog($userCard){
        try {
            Log::notice('Coming add Log');
            $data = [
                'order_no' => $userCard->card_no,
                'order_type' => BalanceLogEnum::ORDER_TYPE_CARD,
                'user_id' => $userCard->user_id,
                'user_type' => $userCard->user_type,
            ];

            // 积分消耗
            $logData = [
                'amount' => $userCard->point,
                'amount_type' => $userCard->pay_unit, // 公益诚信积分 / 善行币
                'change_type' => WalletsEnum::WALLET_LOG_TYPE_OUT,
                'comment' => $userCard->memo
            ];
            // 已经支付
            if( $userCard->pay_status == UserCardsEnum::PAY_STATUS_PAYED) {
                CommonService::recordAmountLog(array_merge($data, $logData));
            }

            // 积分充值
            $logData = [
                'amount' => $userCard->value_sxcx,
                'amount_type' => $userCard->card_type,
                'change_type' => WalletsEnum::WALLET_LOG_TYPE_IN,
                'comment' => sprintf(CardEnum::CMZJ_BUY_CONTENT, CardEnum::CARD_NAME[$userCard->card_type])
            ];
            // 已经到账
            if( $userCard->pay_status == UserCardsEnum::VALUE_DISPATCH_STATUS_DONE) {
                CommonService::recordAmountLog(array_merge($data, $logData));
            }
        }catch (\Exception $e) {
            Log::error(' Async queue, CmzjScheduleNotification _addLog error. '. $e->getMessage());
        }
    }
}
